iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 24
1
Modern Web

從0.5開始的JavaScript系列 第 24 篇

Day24 Promise 詳解(2/2)

  • 分享至 

  • xImage
  •  

昨日講完了 Promise 的特性與基本用法,今日再來討論更深入的應用。

Promise

首先就是剩下的兩個方法: Promise.all、Promise.race。

Promise.all

Promise.all 能夠將傳入的多個 Promise 同時執行(平行處理),並且等到所有傳入的 Promise 都回應狀態後,才會進入 then,而 then 中的 resolve function 傳入的參數即為一開始傳入的所有 Pormise 的 resolve 回傳值。

這邊一樣呼叫昨天網美小花的例子,

var willTogether = function(money) {
    return new Promise(function (resolve, reject) {
      if(money > 100) {
          resolve("我愛你 " + money + " 元先生");
      } else {
          reject(new Error('你是一個好人,但你值得更好的人'));
      }
    });
}

我們昨天的範例是一次只有一位追求者,所以 300 元先生必須等到網美小花回應 200 元先生後,才能進行追求,

willTogether(200)
.then(function(val) {
    // 當網美小花回應 Mr.200 後
    // Mr.300 接著追求
    return willTogether(300);
})
.then(function(val) {
    // 網美小花回應 Mr.300
})
.catch(function(err) {
    console.log(err);
});

But

現實生活中有這種事情,追求者會輪流排隊嗎?

好人卡多到可以打牌的小王覺得不行!

為了更貼近真實案例,所有追求者應該是同時追求,但是還是為了公平,所以會等到網美小花回應所有追求者後,再由他統一公布所有追求者的結果。

而好人小王就是 Promise.all,程式碼可以寫成這樣,

Promise.all([willTogether(200), willTogether(300)])
.then(function(val) {
    console.log(val);
    // ["我愛你 200 元先生", "我愛你 300 元先生"]
})

因為傳入多個 Promise,所有結果會存到一個陣列中。

好人小王覺得自己提供追求者更多機會,網美小花也同時有了多個男友,可喜可賀、可喜可賀。

重點整理

Promise.all :

  1. 用 Array 包起來,能夠傳入多個 Promise 同時執行。
  2. 等到所有 Promise 回傳狀態後,才會接著進行下一步。
  3. then 的 resolve function 將會收到所有 Promise 回傳的結果。

但是使用上要非常注意,因為只要傳入的 Promise 中有一個 reject,將會導致直接進入 catch,也不會收到其他 resolve 狀態的回傳值。

像是這樣,就算 willTogether(200) 的狀態應該會是 resolve,但是 willTogether(50) 的 reject 導致直接進入 catch,then 中也不會印出 Mr.200。

Promise.all([willTogether(200), willTogether(50)])
.then(function(val) {
    console.log(val); // 不會顯示出 Mr.200
})
.catch(function(err) {
    console.log(err); // sorry
})

簡單來講,就是只要有一個失敗,其他人也涼啦!

Promise.race

上方都理解後,Promise.race 也差不多理解了,它和 Promise.all 的差別在於,Promise.race 只要有一個完成,就會進入 then,不會等剩下的 Promise。

我們把程式碼改一下,讓網美小花的變成來者不拒,但是考慮時間變成隨機(0~3秒),
順便也把函數改成箭頭函式的寫法:

var willTogether = (name) => {
    return new Promise((resolve, reject) => {
        var s = Math.floor(Math.random() * 4);
        setTimeout(() => resolve("恭喜你: " + name), s * 1000);
    });
}

忘記箭頭函式的可以到 Day6 複習。

接下來就是有多個競爭者同時追求,看誰最幸運,第一個被網美小花回應!

Promise.race([willTogether("Bob"), willTogether("Tom"), willTogether("Ken")])
.then(function(val) {
    console.log(val); // 顯示第一個完成的
})
.catch(function(err) {
    console.log(err);
})

執行結果(每次都不一樣)

至此 Promise 的四個方法都已講完

  • Promise.resolve
  • Promise.reject
  • Promise.all
  • Promise.race

下一篇會介紹被譽為處理非同步的最佳方案: await、async。

今日的分享就到這,我們明天見/images/emoticon/emoticon51.gif


上一篇
Day23 Promise 詳解(1/2)
下一篇
Day25 優雅的 Await、Async
系列文
從0.5開始的JavaScript 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言